#include "oeexcelreader.h"

#include <libxl.h>

using namespace libxl;

class OEExcelReaderPrivate {
    OEExcelReaderPrivate(OEExcelReader* parent)
        :q_ptr(parent),lastSheet_(0), readNum_(0){
    }
private:

    // 工作簿
    Book *pWB;
    // 工作表
    Sheet *pWS;

    QString lastFileName_;

    int lastSheet_;
    int readNum_;
private:

    OEExcelReader * const q_ptr;
    Q_DECLARE_PUBLIC(OEExcelReader)
};

OEExcelReader::OEExcelReader(QString _fileName)
    :d_ptr(new OEExcelReaderPrivate(this))
{
    Q_D(OEExcelReader);

    d->pWB = xlCreateBook();

    if (!d->pWB->load(_fileName.toLocal8Bit().data()))
        return;


    d->lastFileName_ = _fileName;

    d->pWS = d->pWB->getSheet(0);
    if (!d->pWS)
        return;
}

OEExcelReader::~OEExcelReader()
{
    closeWorkBook();
}

int OEExcelReader::createWorkbooks()
{
    Q_D(OEExcelReader);

    // 1247 完成初始化操作后，试图再次运行初始化操作。
    if (d->pWB != Q_NULLPTR)
        return 1247;

    d->pWB = xlCreateBook();

    if (d->pWB == Q_NULLPTR)
        return -1;
    return 0;
}

int OEExcelReader::load(QString _fileName)
{
    Q_D(OEExcelReader);

    if (!d->pWB->load(_fileName.toLocal8Bit().data()))
        return -1;

    d->lastFileName_ = _fileName;

    return 0;
}

int OEExcelReader::selectSheet(int sheetIndex)
{
    Q_D(OEExcelReader);

    d->pWS = d->pWB->getSheet(sheetIndex);
    if (!d->pWS)
        return -1;

    d->lastSheet_ = sheetIndex;

    return 0;
}

int OEExcelReader::getSheetsCount()
{
    Q_D(OEExcelReader);

    if (d->pWB == Q_NULLPTR)
        return -1;

    return d->pWB->sheetCount();
}

QString OEExcelReader::getSheetName(int sheetIndex)
{
    Q_D(OEExcelReader);

    if (d->pWB != Q_NULLPTR)
        return QString(d->pWB->getSheet(sheetIndex)->name());

    return "";
}

double OEExcelReader::getCellDoubleValue(int row, int column)
{

    Q_D(OEExcelReader);

    // 破解读取300次的限制
    if (d->readNum_ > 200) {

        closeWorkBook();
        if (0 != createWorkbooks()) {
            return -1;
        }

        if (0 != load(d->lastFileName_)) {
            return -1;
        }

        // 工作表
        if (0 != selectSheet(d->lastSheet_)) {
            return -1;
        }
    }


    double ret_data;

    CellType data_type = d->pWS->cellType(row,column);

    switch(data_type) {
    //enum CellType {CELLTYPE_STRING, CELLTYPE_BOOLEAN, CELLTYPE_BLANK, CELLTYPE_ERROR};
    case CellType::CELLTYPE_NUMBER: {
        ret_data = d->pWS->readNum(row,column);
        break;
    }

    default:
        ret_data = -1;
    }

    ++(d->readNum_);

    return ret_data;
}

QString OEExcelReader::getCellValue(int row, int column)
{
    Q_D(OEExcelReader);

    // 破解读取300次的限制
    if (d->readNum_ > 200) {
        closeWorkBook();
        if (0 != createWorkbooks()) {
            return "error";
        }

        if (0 != load(d->lastFileName_)) {
            return "error";
        }

        // 工作表
        if (0 != selectSheet(d->lastSheet_)) {
            return "error";
        }
        d->readNum_ = 0;
    }


    QString ret_data;

    CellType data_type = d->pWS->cellType(row,column);

    switch(data_type) {
    //enum CellType {CELLTYPE_STRING, CELLTYPE_BOOLEAN, CELLTYPE_BLANK, CELLTYPE_ERROR};
    case CellType::CELLTYPE_NUMBER: {
        double num = d->pWS->readNum(row,column);
        ret_data = QString::number(num,10,4);
        break;
    }
    case CellType::CELLTYPE_STRING:
        ret_data = d->pWS->readStr(row,column);
        break;

    default:
        ret_data = "not read";
    }

    ++(d->readNum_);

    return ret_data;
}

int OEExcelReader::getUsedRowsCount()
{
    Q_D(OEExcelReader);
    if (d->pWS == Q_NULLPTR)
        return -1;

    return d->pWS->lastRow();
}

int OEExcelReader::getUsedColsCount()
{
    Q_D(OEExcelReader);
    if (d->pWS == Q_NULLPTR)
        return -1;

    return d->pWS->lastCol();
}

void OEExcelReader::closeWorkBook()
{
    Q_D(OEExcelReader);

    d->pWB->release();
    d->pWB = Q_NULLPTR;
    d->pWS = Q_NULLPTR;
}
